package com.szpxt.service;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.List;
import java.util.Map;

import org.activiti.engine.IdentityService;
import org.activiti.engine.impl.persistence.entity.UserEntity;
import org.apache.commons.lang.StringUtils;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.stereotype.Component;

import com.szpxt.model.Organization;
import com.szpxt.model.Role;
import com.szpxt.model.User;

import sun.misc.BASE64Encoder;

@Component
public class UserService extends HibernateDaoSupport {
	
	private OrganizationService organizationService;
	private RoleService roleService;
	
	private IdentityService identityService;

	public User saveOrUpdate(Map<String, String> map) throws NoSuchAlgorithmException, UnsupportedEncodingException {
		User user = new User();
		
		String id = map.get("id");
		String name = map.get("name");
		String password = map.get("password");
		String organizationId = map.get("organizationId");
		String roleId = map.get("roleId");
		
		if(!StringUtils.isBlank(id)) {
			user = get(Long.parseLong(id));
		}
		
		if(!StringUtils.isBlank(password)) {
			MessageDigest messageDigest = MessageDigest.getInstance("MD5");
			BASE64Encoder encoder = new BASE64Encoder();
			password = encoder.encode(messageDigest.digest(password.getBytes("UTF-8")));
			user.setPassword(password);
		}
		
		Organization organization = organizationService.get(Long.parseLong(organizationId));
		Role role = roleService.get(Long.parseLong(roleId));
		
		user.setName(name);
		user.setOrganization(organization);
		user.setRole(role);
		
		getHibernateTemplate().saveOrUpdate(user);
		
		if(StringUtils.isBlank(id)) {		//新增，activiti相应新增
			UserEntity userEntity = new UserEntity();
			userEntity.setFirstName(user.getId() + "");
			identityService.saveUser(userEntity);
			
			user.setActivitiId(userEntity.getId());			//双向保存
			getHibernateTemplate().saveOrUpdate(user);
		}
		
		return user;
	}
	
	public List<User> list(long organizationId, int start, int limit, String query) {
		Organization organization = organizationService.get(organizationId);
		
		DetachedCriteria criteria = DetachedCriteria.forClass(User.class);
		criteria.add(Restrictions.eq("organization", organization));
		if(!StringUtils.isBlank(query)) {
			criteria.add(Restrictions.like("name", query, MatchMode.ANYWHERE));
		}
		
		return (List<User>)getHibernateTemplate().findByCriteria(criteria, start, limit);
	}
	
	public long getTotalCount(long organizationId, String query) {
		Organization organization = organizationService.get(organizationId);
		
		DetachedCriteria criteria = DetachedCriteria.forClass(User.class);
		criteria.add(Restrictions.eq("organization", organization));
		if(!StringUtils.isBlank(query)) {
			criteria.add(Restrictions.like("name", query, MatchMode.ANYWHERE));
		}
		
		criteria.setProjection(Projections.rowCount());
		
		return (Long)getHibernateTemplate().findByCriteria(criteria).get(0);
	}
	
	public User get(long id) {
		DetachedCriteria criteria = DetachedCriteria.forClass(User.class);
		criteria.add(Restrictions.eq("id", id));
		
		return (User)getHibernateTemplate().findByCriteria(criteria).get(0);
	}
	
	public void delete(long id) {
		User user = get(id);
		getHibernateTemplate().delete(user);
	}
	
	public User login(String name, String password) throws NoSuchAlgorithmException {
		MessageDigest messageDigest = MessageDigest.getInstance("MD5");
		BASE64Encoder encoder = new BASE64Encoder();
		password = encoder.encode(messageDigest.digest(password.getBytes()));
		
		DetachedCriteria criteria = DetachedCriteria.forClass(User.class);
		criteria.add(Restrictions.eq("name", name));
		criteria.add(Restrictions.eq("password", password));
		
		List listUser = getHibernateTemplate().findByCriteria(criteria);
		return listUser.size() == 0 ? null : (User)listUser.get(0);
	}

	public List<User> getAnalysts() {
		DetachedCriteria criteria = DetachedCriteria.forClass(User.class);
		criteria.createAlias("role", "role");
		criteria.createAlias("role.listPrivilege", "listPrivilege");
		criteria.add(Restrictions.eq("listPrivilege.key", "privilege_handleFinancing"));
		
		return getHibernateTemplate().findByCriteria(criteria);
	}
	
	public User getRandomAnalyst() {
		List<User> listAnalysts = getAnalysts();
		while(true) {
			int random = (int)(listAnalysts.size() * Math.random());
			if(random < listAnalysts.size()) {
				return listAnalysts.get(random);
			}
		}
	}
	
	//获取和设置方法
	public OrganizationService getOrganizationService() {
		return organizationService;
	}

	public void setOrganizationService(OrganizationService organizationService) {
		this.organizationService = organizationService;
	}

	public RoleService getRoleService() {
		return roleService;
	}

	public void setRoleService(RoleService roleService) {
		this.roleService = roleService;
	}

	public IdentityService getIdentityService() {
		return identityService;
	}

	public void setIdentityService(IdentityService identityService) {
		this.identityService = identityService;
	}
	
}
